package com.jysz.certificate.service.cm;

import java.io.File;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Service;

import com.jysz.certificate.persistence.dao.cm.CertificateRenewDao;
import com.jysz.certificate.persistence.enums.AttachmentType;
import com.jysz.certificate.persistence.enums.CertificateRenewState;
import com.jysz.certificate.persistence.enums.CertificationType;
import com.jysz.certificate.persistence.enums.CopyOfCertificationImporting;
import com.jysz.certificate.persistence.enums.WorkflowOperateType;
import com.jysz.certificate.persistence.enums.WorkflowState;
import com.jysz.certificate.persistence.enums.WorkflowType;
import com.jysz.certificate.persistence.model.cm.CertificateRenew;
import com.jysz.certificate.persistence.model.cm.Certification;
import com.jysz.certificate.persistence.model.cm.RenewObject;
import com.jysz.certificate.persistence.model.cs.TheNetwork;
import com.jysz.certificate.persistence.model.system.Shop;
import com.jysz.certificate.persistence.model.system.User;
import com.jysz.certificate.persistence.model.workflow.Workflow;
import com.jysz.certificate.service.core.AttachmentService;
import com.jysz.certificate.service.system.ShopService;
import com.jysz.certificate.service.workflow.WorkflowService;
import com.jysz.certificate.utils.DateUtil;
import com.jysz.webcore.ssh.orm.hibernate.support.Page;
import com.jysz.webcore.ssh.service.EntityService;
import com.jysz.webcore.utils.SshBeanUtils;

/**
 * 换证
 * 
 * @author <a href="mailto:javaengine@outlook.com">Kaca Rich</a>
 *
 */
@Service
public class CertificateRenewService  extends EntityService<CertificateRenew, Long, CertificateRenewDao>{

	@Resource
	public CertificateRenewDao certificateRenewDao;
	
	@Resource
	private AttachmentService attachmentService;
	
	@Resource
	private WorkflowService workflowService;
	@Resource
	private ShopService shopService;
	@Resource
	private CertificationService certificationService;
	
	@Override
	public CertificateRenewDao getEntityDao() {
		return certificateRenewDao;
	}

	public Page<CertificateRenew> findPage(CertificateRenew search, int currentPage,
			int pageSize) {
		Criteria criteria = certificateRenewDao.createCriteria();
		criteria.addOrder(Order.asc("state"));
		criteria.addOrder(Order.desc("applyDate"));
		Criteria shopCriteria = null;
		if(search != null){
			if(StringUtils.isNotBlank(search.getApplyNum())){
				criteria.add(Restrictions.like("applyNum", search.getApplyNum(), MatchMode.START));
			}
			
			if(search.getShop() != null && StringUtils.isNotBlank(search.getShop().getShopName())){
				shopCriteria = criteria.createCriteria("shop").add(Restrictions.like("shopName", search.getShop().getShopName(), MatchMode.START));
			}
			
			if(search.getFinancial() != null && StringUtils.isNotBlank(search.getFinancial().getName())){
				criteria.createCriteria("financial").add(Restrictions.like("name", search.getFinancial().getName(), MatchMode.START));
			}
			
			if(search.getState() != null && search.getState().getIndex() > -1){
				criteria.add(Restrictions.eq("state", search.getState()));
			}
		}
		
		if(shopCriteria != null){
			this.addShopCriteria(shopCriteria, true, null);
		}else{
			this.addShopCriteria(criteria, false, null);
		}
		
		
		return this.findPage(criteria, currentPage, pageSize);
	}

	protected void addShopCriteria(Criteria criteria, boolean b, User user) {
		this.getEntityDao().addShopCriteria(criteria, b, user);
	}

	public void save(User user, CertificateRenew entity, File file,
			String fileFileName) {
//		this.syncInCf(entity);
		this.save(entity);
		
		//上传附件
		if(file != null){
			attachmentService.addFile(user, AttachmentType.RENEW, file, entity.getId(), fileFileName);
		}
			
		
	}

	/**
	 * 同步该实体下所有入库合格证的店铺，金融机构，渠道。
	 * @param entity
	 */
	public void syncInCf(CertificateRenew entity) {
		List<RenewObject> renewObjects = entity.getInCertificateRenews();
		Shop shop = shopService.find(entity.getShop().getId());
		if(renewObjects != null){
			for (Iterator<RenewObject> iterator = renewObjects.iterator(); iterator
					.hasNext();) {
				RenewObject renewObject = iterator.next();
				
				renewObject.setShop(shop);
				renewObject.setFinancial(entity.getFinancial());
				
				if(entity.getBrand() != null){
					renewObject.setBrand(entity.getBrand());
				}else if(renewObject.getBrand() != null && (shop.getBrands() == null || (!shop.getBrands().contains(renewObject.getBrand())))){
					renewObject.setBrand(null);
				}
				
			}
		}
		
	}

	public void saveAndSubmit(User user, CertificateRenew entity, File file, String fileFileName,String msg) {
//		this.syncInCf(entity);
		this.save(entity);
		Workflow wf = workflowService.find(WorkflowType.RENEW, entity.getId());
		if(wf == null){
			submitNewWorkflow(user, entity.getId());
		}else{
			//如果之前发起过流程。更改流程状态即可。(可能是被退回的释放单)
			if(!StringUtils.isNotBlank(msg)){
				msg = "重新提交换证流程";
			}
			workflowService.audit(user, wf,WorkflowState.SUBMITED,WorkflowOperateType.SUBMIT, msg);
		}
			
			
			
		//上传附件
		if(file!=null){
			attachmentService.addFile(user, AttachmentType.RENEW, file, entity.getId(), fileFileName);
		}
		
	}
	
	/**
	 * 发起新流程,状态为已提交
	 * @param currentUser
	 * @param id
	 */
	public void submitNewWorkflow(User currentUser,Long id){
		WorkflowState ws=null;
		String msg=null;
		
		ws = WorkflowState.SUBMITED;
//		if(currentUser.getPost() == PostType.Shop){
//			ws=WorkflowState.SUBMITED;
//			msg="提交换证流程";
//		}else{
//			ws=WorkflowState.FINISH;
//			msg="监管科直接完成换证流程";
//		}
		Workflow w = workflowService.find(WorkflowType.RENEW, id);
		if(w != null){//判断是否存在该流程！
			workflowService.audit(currentUser, w, WorkflowState.SUBMITED, WorkflowOperateType.SUBMIT, msg);
		}else{
			workflowService.addWorkflow(currentUser, id, ws, WorkflowType.RENEW, CertificateRenew.class, msg);
		}
	
	}

	public void audit(User user, Long id, String auditMsg,
			WorkflowOperateType ot) {
		CertificateRenew entity = this.find(id);
		
		Workflow wf = workflowService.find(WorkflowType.RENEW, id);
		
		//退回（只有全部退回）
		if(WorkflowOperateType.REFUSE.equals(ot)){
			entity.setState(CertificateRenewState.REFUSED);
			workflowService.audit(user, wf, WorkflowState.REFUSED, WorkflowOperateType.REFUSE, auditMsg);
		}else{
			Set<Certification> outCertifications = entity.getOutCertifications();
			
			for (Iterator<Certification> iterator = outCertifications.iterator(); iterator
					.hasNext();) {
				Certification certification = iterator.next();
				
				certification.setCertificateRenew(entity);
//				certification.setState(CertificationType.RENEWPASS);
				certificationService.save(certification);
			}
			entity.setState(CertificateRenewState.PASSED);
			workflowService.audit(user, wf, WorkflowState.PASS, WorkflowOperateType.PASS, auditMsg);
		}
		
		this.save(entity);
	}

	/**
	 * 确认收证
	 * 
	 * @param user
	 * @param id
	 */
	public void confirmAccept(User user, Long id) {
		CertificateRenew entity = this.find(id);
		Workflow wf = workflowService.find(WorkflowType.RENEW, id);
		
		Set<Certification> outCertifications = entity.getOutCertifications();
		
		for (Iterator<Certification> iterator = outCertifications.iterator(); iterator
				.hasNext();) {
			Certification certification = iterator.next();
			
			certification.setCertificateRenew(entity);
			certification.setState(CertificationType.RENEWOUT);
			certification.setLeaveDate(DateUtil.getDate());
			certificationService.save(certification);
			
		}
		
		List<RenewObject> renewObjects = entity.getInCertificateRenews();
		
		for (Iterator<RenewObject> iterator = renewObjects.iterator(); iterator.hasNext();) {
			RenewObject renewObject = iterator.next();
			Certification inCertification = new Certification();
			SshBeanUtils.copyProperties(renewObject, inCertification, new String[]{"financial","shop", "brand", "draft", "motorcycleType", "orderNumber", "chassis", "draftBeginDate", "certificationNum", "draftEndDate", "engine", "supplyPrice","cmImporting"});
			
			inCertification.setCertificateRenew(entity);
			inCertification.setState(CertificationType.INSTOCK);
			inCertification.setWarehouseDate(DateUtil.getDate());
			inCertification.setCmImporting(CopyOfCertificationImporting.RENEW);
			certificationService.save(inCertification);
		}
		entity.setState(CertificateRenewState.FINISH);
		workflowService.audit(user, wf, WorkflowState.FINISH, WorkflowOperateType.FINISH, "");
		this.save(entity);
	}
		
	
	public void destory(Long id) {
		super.destory(id);
		
		workflowService.destory(id, WorkflowType.RENEW);
		attachmentService.delFile(id, AttachmentType.RENEW);
	}

	/**
	 * @param certification
	 * @return
	 */
	public List<CertificateRenew> findByCertification(
			Certification certification) {
		Criteria criteria = this.getEntityDao().createCriteria();
		criteria.createCriteria("outCertifications").add(Restrictions.eq("id", certification.getId()));
		return criteria.list();
	}
	
}
